package com.moodbox.server.ai.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.moodbox.server.ai.service.AiAnalysisService;
import com.moodbox.server.common.service.SensitiveWordService;
import com.moodbox.server.mood.entity.Mood;
import com.moodbox.server.mood.mapper.MoodMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class OpenAiAnalysisServiceImpl implements AiAnalysisService {

    @Value("${openai.api-key}")
    private String apiKey;

    @Value("${openai.api-url}")
    private String apiUrl;

    @Value("${openai.timeout:30}")
    private int timeout;

    @Value("${openai.max-retries:2}")
    private int maxRetries;

    private final MoodMapper moodMapper;
    private final SensitiveWordService sensitiveWordService;

    @Override
    public MoodAnalysisResult analyzeMood(
        String textContent, 
        MultipartFile image, 
        MultipartFile audio
    ) {
        // 过滤敏感词
        String filteredContent = sensitiveWordService.filterSensitiveWord(textContent);
        
        // 检查是否包含敏感词
        if (sensitiveWordService.containsSensitiveWord(textContent)) {
            log.warn("输入内容包含敏感词，已进行过滤");
        }

        int retries = 0;
        while (retries <= maxRetries) {
            try {
                // 构建分析请求
                JSONObject requestBody = new JSONObject();
                requestBody.set("model", "gpt-4o");
                
                List<JSONObject> messages = new ArrayList<>();
                JSONObject systemPrompt = new JSONObject();
                systemPrompt.set("role", "system");
                systemPrompt.set("content", "你是一个专业的情绪分析助手。请根据用户提供的文字、图片和语音内容，准确识别用户的情绪状态。");
                messages.add(systemPrompt);

                JSONObject userPrompt = new JSONObject();
                userPrompt.set("role", "user");
                
                // 构建分析内容
                StringBuilder contentBuilder = new StringBuilder();
                if (filteredContent != null && !filteredContent.isEmpty()) {
                    contentBuilder.append("文字内容：").append(filteredContent).append("\n");
                }
                
                // 如果有图片或语音，添加提示
                if (image != null) {
                    contentBuilder.append("包含图片文件\n");
                }
                if (audio != null) {
                    contentBuilder.append("包含语音文件\n");
                }
                
                contentBuilder.append("请分析以下内容，给出：\n");
                contentBuilder.append("1. 情绪标签（如：开心、悲伤、焦虑等）\n");
                contentBuilder.append("2. 情绪置信度（0-1的浮点数）\n");
                contentBuilder.append("3. 简短的情绪描述\n");
                
                userPrompt.set("content", contentBuilder.toString());
                messages.add(userPrompt);

                requestBody.set("messages", messages);
                requestBody.set("max_tokens", 200);
                requestBody.set("temperature", 0.7);

                // 发送请求
                HttpResponse response = HttpRequest.post(apiUrl + "/chat/completions")
                    .header("Authorization", "Bearer " + apiKey)
                    .header("Content-Type", "application/json")
                    .body(requestBody.toString())
                    .timeout(timeout * 1000)  // 超时时间
                    .execute();

                // 检查响应状态码
                if (response.getStatus() != 200) {
                    log.error("OpenAI API调用失败，状态码：{}", response.getStatus());
                    throw new RuntimeException("OpenAI API调用失败");
                }

                // 解析响应
                JSONObject responseJson = JSONUtil.parseObj(response.body());
                String analysisText = responseJson.getJSONArray("choices")
                    .getJSONObject(0)
                    .getJSONObject("message")
                    .getStr("content");

                // 解析分析结果
                MoodAnalysisResult result = parseAnalysisResult(analysisText);
                log.info("AI分析成功：{}", result);
                return result;
            } catch (Exception e) {
                retries++;
                log.warn("AI分析第{}次重试，错误：{}", retries, e.getMessage());
                
                // 重试间隔
                if (retries <= maxRetries) {
                    try {
                        TimeUnit.SECONDS.sleep(2 * retries);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }

        // 最终降级处理
        log.error("AI分析多次重试失败，返回默认结果");
        return getDefaultAnalysisResult(filteredContent);
    }

    @Override
    public String generateFunReport(Mood mood) {
        // 过滤敏感词
        String filteredContent = sensitiveWordService.filterSensitiveWord(mood.getTextContent());
        
        // 检查是否包含敏感词
        if (sensitiveWordService.containsSensitiveWord(mood.getTextContent())) {
            log.warn("心情记录包含敏感词，已进行过滤");
        }

        // 使用过滤后的内容创建新的Mood对象
        Mood filteredMood = new Mood()
            .setEmotionTag(mood.getEmotionTag())
            .setEmotionIntensity(mood.getEmotionIntensity())
            .setTextContent(filteredContent);

        int retries = 0;
        while (retries <= maxRetries) {
            try {
                JSONObject requestBody = new JSONObject();
                requestBody.set("model", "gpt-4o");
                
                List<JSONObject> messages = new ArrayList<>();
                JSONObject systemPrompt = new JSONObject();
                systemPrompt.set("role", "system");
                systemPrompt.set("content", "你是一个有趣的情绪报告生成器。使用轻松、幽默的语气，为用户生成有趣的情绪报告。");
                messages.add(systemPrompt);

                JSONObject userPrompt = new JSONObject();
                userPrompt.set("role", "user");
                
                StringBuilder contentBuilder = new StringBuilder();
                contentBuilder.append("情绪标签：").append(filteredMood.getEmotionTag()).append("\n");
                contentBuilder.append("情绪强度：").append(filteredMood.getEmotionIntensity()).append("\n");
                contentBuilder.append("文字内容：").append(filteredMood.getTextContent()).append("\n");
                
                contentBuilder.append("请为这份心情记录生成一份有趣、轻松的情绪报告。报告应该：\n");
                contentBuilder.append("1. 使用幽默、轻松的语气\n");
                contentBuilder.append("2. 给出一些积极的建议或安慰\n");
                contentBuilder.append("3. 控制在100-150字\n");
                
                userPrompt.set("content", contentBuilder.toString());
                messages.add(userPrompt);

                requestBody.set("messages", messages);
                requestBody.set("max_tokens", 200);
                requestBody.set("temperature", 0.8);

                HttpResponse response = HttpRequest.post(apiUrl + "/chat/completions")
                    .header("Authorization", "Bearer " + apiKey)
                    .header("Content-Type", "application/json")
                    .body(requestBody.toString())
                    .timeout(timeout * 1000)
                    .execute();

                // 检查响应状态码
                if (response.getStatus() != 200) {
                    log.error("OpenAI API调用失败，状态码：{}", response.getStatus());
                    throw new RuntimeException("OpenAI API调用失败");
                }

                JSONObject responseJson = JSONUtil.parseObj(response.body());
                String report = responseJson.getJSONArray("choices")
                    .getJSONObject(0)
                    .getJSONObject("message")
                    .getStr("content");

                log.info("趣味报告生成成功");
                return report;
            } catch (Exception e) {
                retries++;
                log.warn("趣味报告第{}次重试，错误：{}", retries, e.getMessage());
                
                if (retries <= maxRetries) {
                    try {
                        TimeUnit.SECONDS.sleep(2 * retries);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }

        // 降级处理
        log.error("趣味报告生成多次重试失败");
        return getDefaultFunReport(filteredMood);
    }

    @Override
    public String generateWeekReport(String userId) {
        int retries = 0;
        while (retries <= maxRetries) {
            try {
                // 获取本周心情记录
                LocalDateTime startOfWeek = LocalDateTime.of(
                    LocalDate.now().with(java.time.DayOfWeek.MONDAY),
                    LocalTime.MIN
                );
                LocalDateTime endOfWeek = LocalDateTime.of(
                    LocalDate.now().with(java.time.DayOfWeek.SUNDAY),
                    LocalTime.MAX
                );

                List<Mood> weekMoods = moodMapper.selectList(
                    new LambdaQueryWrapper<Mood>()
                        .eq(Mood::getUserId, userId)
                        .between(Mood::getCreateTime, startOfWeek, endOfWeek)
                );

                // 如果本周没有记录，返回默认提示
                if (weekMoods.isEmpty()) {
                    return "本周还没有心情记录，快来记录你的第一份心情吧！";
                }

                JSONObject requestBody = new JSONObject();
                requestBody.set("model", "gpt-4o");
                
                List<JSONObject> messages = new ArrayList<>();
                JSONObject systemPrompt = new JSONObject();
                systemPrompt.set("role", "system");
                systemPrompt.set("content", "你是一个专业的情绪分析师。根据用户本周的心情记录，生成一份有洞察力的周报。");
                messages.add(systemPrompt);

                JSONObject userPrompt = new JSONObject();
                userPrompt.set("role", "user");
                
                StringBuilder contentBuilder = new StringBuilder();
                contentBuilder.append("本周心情记录数量：").append(weekMoods.size()).append("\n");
                contentBuilder.append("心情记录详情：\n");
                
                for (Mood mood : weekMoods) {
                    contentBuilder.append("- 日期：").append(mood.getCreateTime())
                        .append(", 情绪：").append(mood.getEmotionTag())
                        .append(", 强度：").append(mood.getEmotionIntensity())
                        .append("\n");
                }
                
                contentBuilder.append("请为这份周报生成：\n");
                contentBuilder.append("1. 本周情绪整体分析\n");
                contentBuilder.append("2. 情绪变化趋势\n");
                contentBuilder.append("3. 给用户的建议\n");
                contentBuilder.append("4. 控制在200字以内\n");
                
                userPrompt.set("content", contentBuilder.toString());
                messages.add(userPrompt);

                requestBody.set("messages", messages);
                requestBody.set("max_tokens", 250);
                requestBody.set("temperature", 0.7);

                HttpResponse response = HttpRequest.post(apiUrl + "/chat/completions")
                    .header("Authorization", "Bearer " + apiKey)
                    .header("Content-Type", "application/json")
                    .body(requestBody.toString())
                    .timeout(timeout * 1000)
                    .execute();

                // 检查响应状态码
                if (response.getStatus() != 200) {
                    log.error("OpenAI API调用失败，状态码：{}", response.getStatus());
                    throw new RuntimeException("OpenAI API调用失败");
                }

                JSONObject responseJson = JSONUtil.parseObj(response.body());
                String weekReport = responseJson.getJSONArray("choices")
                    .getJSONObject(0)
                    .getJSONObject("message")
                    .getStr("content");

                log.info("周报生成成功");
                return weekReport;
            } catch (Exception e) {
                retries++;
                log.warn("周报生成第{}次重试，错误：{}", retries, e.getMessage());
                
                if (retries <= maxRetries) {
                    try {
                        TimeUnit.SECONDS.sleep(2 * retries);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                    }
                }
            }
        }

        // 降级处理
        log.error("周报生成多次重试失败");
        return getDefaultWeekReport(userId);
    }

    /**
     * 解析AI分析结果
     * @param analysisText AI返回的分析文本
     * @return 解析后的分析结果
     */
    private MoodAnalysisResult parseAnalysisResult(String analysisText) {
        MoodAnalysisResult result = new MoodAnalysisResult();
        
        // 简单的正则匹配
        String[] lines = analysisText.split("\n");
        for (String line : lines) {
            if (line.contains("情绪标签")) {
                result.emotionTag = line.split("：")[1].trim();
            } else if (line.contains("情绪置信度")) {
                try {
                    result.emotionConfidence = Double.parseDouble(line.split("：")[1].trim());
                } catch (Exception e) {
                    result.emotionConfidence = 0.5;
                }
            } else if (line.contains("情绪描述")) {
                result.emotionDescription = line.split("：")[1].trim();
            }
        }

        // 兜底处理
        if (result.emotionTag == null) result.emotionTag = "未知";
        if (result.emotionConfidence == null) result.emotionConfidence = 0.5;
        if (result.emotionDescription == null) result.emotionDescription = "情绪状态平稳";

        return result;
    }

    /**
     * 获取默认的分析结果
     * @param textContent 文字内容
     * @return 默认分析结果
     */
    private MoodAnalysisResult getDefaultAnalysisResult(String textContent) {
        MoodAnalysisResult defaultResult = new MoodAnalysisResult();
        defaultResult.emotionTag = "中性";
        defaultResult.emotionConfidence = 0.5;
        
        // 根据文字内容给出简单的情绪判断
        if (textContent != null && !textContent.isEmpty()) {
            if (containsPositiveWords(textContent)) {
                defaultResult.emotionTag = "积极";
                defaultResult.emotionConfidence = 0.7;
                defaultResult.emotionDescription = "文字内容显示积极情绪";
            } else if (containsNegativeWords(textContent)) {
                defaultResult.emotionTag = "消极";
                defaultResult.emotionConfidence = 0.6;
                defaultResult.emotionDescription = "文字内容显示消极情绪";
            } else {
                defaultResult.emotionDescription = "情绪状态平稳";
            }
        }

        return defaultResult;
    }

    /**
     * 获取默认的趣味报告
     * @param mood 心情记录
     * @return 默认趣味报告
     */
    private String getDefaultFunReport(Mood mood) {
        String[] defaultReports = {
            "今天的心情很特别，值得被记录和珍惜！",
            "生活就像一杯茶，苦乐参半，但总有温暖的时刻。",
            "每一种情绪都是生活的调味料，让我们的生活更丰富多彩。"
        };
        return defaultReports[(int)(Math.random() * defaultReports.length)];
    }

    /**
     * 获取默认的周报
     * @param userId 用户ID
     * @return 默认周报
     */
    private String getDefaultWeekReport(String userId) {
        return "本周的心情记录很丰富，继续保持记录的好习惯！每一天都是值得被铭记的。";
    }

    /**
     * 检查文本是否包含积极词汇
     * @param text 文本内容
     * @return 是否包含积极词汇
     */
    private boolean containsPositiveWords(String text) {
        String[] positiveWords = {"开心", "快乐", "高兴", "喜悦", "期待", "兴奋", "满足", "幸福"};
        for (String word : positiveWords) {
            if (text.contains(word)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 检查文本是否包含消极词汇
     * @param text 文本内容
     * @return 是否包含消极词汇
     */
    private boolean containsNegativeWords(String text) {
        String[] negativeWords = {"难过", "伤心", "焦虑", "担心", "压力", "烦恼", "悲伤", "失望"};
        for (String word : negativeWords) {
            if (text.contains(word)) {
                return true;
            }
        }
        return false;
    }
} 